home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
- #ifndef lint
- static char rcsid[] =
- "@(#)$Header: savefile.c,v 1.16 94/06/20 19:07:56 leres Exp $ (LBL)";
- #endif
-
- /*
- * savefile.c - supports offline use of tcpdump
- * Extraction/creation by Jeffrey Mogul, DECWRL
- * Modified by Steve McCanne, LBL.
- *
- * Used to save the received packet headers, after filtering, to
- * a file.
- * The first record in the file contains saved values for the machine
- * dependent values so we can print the dump file on any architecture.
- */
-
- #include <sys/types.h>
- #include <sys/time.h>
-
- #include <errno.h>
- #include <memory.h>
- #include <stdio.h>
- #if __STDC__
- #include <stdlib.h>
- #endif
- #include <unistd.h>
-
- #include "pcap-int.h"
- #include "order.h"
-
-
- static int sf_write_header(pcap_dumper_t *p, int linktype, int thiszone, int snaplen);
-
- /*
- * Initialize so that sf_write() will output to the file named 'fname'.
- */
- pcap_dumper_t *
- pcap_dump_open(pcap_t *p, char *fname, int format)
- {
- pcap_dumper_t *dumper;
- FILE *f;
-
- if ((dumper = malloc(sizeof(*dumper))) == NULL)
- return NULL;
- if (fname[0] == '-' && fname[1] == '\0')
- f = stdout;
- else {
- f = fopen(fname, "w");
- if (f == NULL) {
- sprintf(p->errbuf, "%s: %s",
- fname, pcap_strerror(errno));
- free(dumper);
- return NULL;
- }
- }
- dumper->wfile = f;
- dumper->format = format;
- dumper->swapped = 0;
- if (format == FORMAT_SNOOP2 && byteorder() != BIG_ENDIAN)
- dumper->swapped = 1;
-
- (void)sf_write_header(dumper, p->linktype, p->tzoff, p->snapshot);
-
- return dumper;
- }
-
- /*
- * Output a packet to the initialized dump file.
- */
- void
- pcap_dump(u_char *d, const struct pcap_hdr *h, const u_char *sp)
- {
- pcap_dumper_t *p = (pcap_dumper_t *)d;
- FILE * f = p->wfile;
- struct pcap_pkthdr tcpdump;
- struct pcap_snoop_pkthdr snoop;
- int align = 0;
-
- switch (p->format) {
- case FORMAT_TCPDUMP:
- tcpdump.ts = h->ts;
- tcpdump.caplen = h->caplen;
- tcpdump.len = h->len;
- (void)fwrite((char *)&tcpdump, sizeof(tcpdump), 1, f);
- (void)fwrite((char *)sp, h->caplen, 1, f);
- break;
- case FORMAT_SNOOP2:
- /* there is a compensation here for old versions of snoop that
- can't handle dump files that are not 32-bit aligned */
- snoop.len = h->len;
- snoop.caplen = h->caplen;
- snoop.totlen = sizeof(snoop)+h->caplen;
- #ifndef NO_SNOOP_ALIGN
- if ((align = 4 - (snoop.totlen % 4)) == 4)
- align = 0;
- else
- snoop.totlen += align;
- #endif
- snoop.drops = h->drops;
- snoop.secs = h->ts.tv_sec;
- snoop.usecs = h->ts.tv_usec;
- if (p->swapped) {
- snoop.len = SWAPLONG(snoop.len);
- snoop.caplen = SWAPLONG(snoop.caplen);
- snoop.totlen = SWAPLONG(snoop.totlen);
- snoop.drops = SWAPLONG(snoop.drops);
- snoop.secs = SWAPLONG(snoop.secs);
- snoop.usecs = SWAPLONG(snoop.usecs);
- }
- (void)fwrite((char *)&snoop, sizeof(snoop), 1, f);
- (void)fwrite((char *)sp, h->caplen, 1, f);
- #ifndef NO_SNOOP_ALIGN
- if (align)
- (void)fseek(f, align, SEEK_CUR);
- #endif
- break;
- }
- }
-
- void
- pcap_dump_close(pcap_dumper_t *p)
- {
- FILE *f = p->wfile;
-
- if (f != stdout)
- fclose(f);
- }
-
- static int
- sf_write_header(pcap_dumper_t *p, int linktype, int thiszone, int snaplen)
- {
- FILE *fp = p->wfile;
- struct pcap_file_header hdr;
- struct pcap_file_snoop_header snoop;
-
- switch (p->format) {
- case FORMAT_TCPDUMP:
- hdr.magic = TCPDUMP_MAGIC;
- hdr.version_major = PCAP_VERSION_MAJOR;
- hdr.version_minor = PCAP_VERSION_MINOR;
-
- hdr.thiszone = thiszone;
- hdr.snaplen = snaplen;
- hdr.sigfigs = 0;
- hdr.linktype = linktype;
-
- if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1)
- return -1;
-
- break;
- case FORMAT_SNOOP2:
- memcpy(snoop.id, SNOOP_MAGIC, sizeof(snoop.id));
- snoop.version = 2;
- snoop.linktype = link_type[linktype];
- if (p->swapped)
- swap_snoop(&snoop);
-
- if (fwrite((char *)&snoop, sizeof(snoop), 1, fp) != 1)
- return -1;
-
- break;
- }
-
- return 0;
- }
-